import java.util.function.IntConsumer;

public class Prime3c {
	private static final Runnable[] readyStack = new Runnable[10000];
	private static int readyStackSize;

	static void loop() {
		var s = readyStack;
		for (int n; (n = readyStackSize) > 0; ) {
			var r = s[--n];
			s[n] = null;
			readyStackSize = n;
			r.run();
		}
	}

	static final class IntChan {
		private Runnable waitR;
		private int value;
		private boolean hasValue;

		private void pause(Runnable r) {
			waitR = r;
		}

		private void tryResume() {
			var r = waitR;
			if (r != null) {
				waitR = null;
				int n = readyStackSize;
				readyStack[n] = r;
				readyStackSize = n + 1;
			}
		}

		void put(int v, Runnable r) {
			if (hasValue) {
				pause(() -> {
					value = v;
					hasValue = true;
					tryResume();
					r.run();
				});
				return;
			}
			value = v;
			hasValue = true;
			tryResume();
			r.run();
		}

		void get(IntConsumer c) {
			if (!hasValue) {
				pause(() -> {
					hasValue = false;
					tryResume();
					c.accept(value);
				});
				return;
			}
			hasValue = false;
			tryResume();
			c.accept(value);
		}
	}

	private static void generate(IntChan ch) {
		generate(ch, 2);
	}

	private static void generate(IntChan ch, int i) {
		ch.put(i, () -> generate(ch, i + 1));
	}

	private static void filter(IntChan in, IntChan out, int prime) {
		in.get(i -> {
			if (i % prime != 0)
				out.put(i, () -> filter(in, out, prime));
			else
				filter(in, out, prime);
		});
	}

	public static void main(String[] args) {
		var count = args.length > 0 ? Integer.parseInt(args[0]) : 10000;
		var ch = new IntChan();
		generate(ch);
		new Runnable() {
			int i = 0;
			IntChan ch0 = ch;

			@Override
			public void run() {
				ch0.get(prime -> {
					if (++i == count) {
						System.out.println(prime);
						System.exit(0);
					}
					var ch1 = ch0;
					var ch2 = new IntChan();
					filter(ch1, ch2, prime);
					ch0 = ch2;
					run();
				});
			}
		}.run();
		loop();
	}
}
